﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.XPath;

namespace ServBus.ListForm2010.Common.WFXSNOperator
{
    //Myschema.xsd
    public class XSN_Myschema : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "myschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into myFields
            string refPath = "/xsd:schema/xsd:element[@name='" + InnerXPath + "']/xsd:complexType/xsd:sequence";
            string refDef = string.Format("<xsd:element ref=\"tns:{0}\" minOccurs=\"0\" maxOccurs=\"1\" />",
                p_FieldInfo.UniqueName);
            InsertNode(refPath, refDef);

            //Insert element definition
            InsertNode("/xsd:schema", p_FieldInfo.GetMyschemaElementDef());
        }
    }

    //Sampledata.xml
    public class XSN_Sampledata : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "sampledata.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            InitialMainListID(p_Context.TListInfo.ListID.ToString());
            return rStatus;
        }

        private void InitialMainListID(string p_ListID)
        {
            XPathNavigator xNav = XPathNav.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:Task", XmlNSManager);
            if (xNav != null && xNav.MoveToFirstAttribute())
            {
                xNav.SetValue(p_ListID);
            }
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            InsertDataObjectDef(p_FieldInfo);
            //Insert into myFields
            InsertNode("/dfs:myFields/dfs:dataFields/tns:" + InnerXPath + "", p_FieldInfo.GetTemplateElementDef());
        }

        #region Private Method

        private void InsertDataObjectDef(XFieldInfo p_FieldInfo)
        {
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice))
            {
                //Insert SampledataOptionDSElement
                string _ODSPath = "/dfs:myFields/xd:DataConnection[@Name='OptionDataSourceConnection']/root";
                InsertNode(_ODSPath, p_FieldInfo.GetSampledataOptionDSElementDef());
            }
            else if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.LookUp))
            {
                //Insert SampledataDataObject
                InsertNode("/dfs:myFields", p_FieldInfo.GetSampledataDataObjectDef());
            }
        }

        #endregion
    }

    //Template.xml
    public class XSN_Template : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "template.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            InitialMainListID(p_Context.TListInfo.ListID.ToString());
            return rStatus;
        }

        private void InitialMainListID(string p_ListID)
        {
            XPathNavigator xNav = XPathNav.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:Task", XmlNSManager);
            if (xNav != null && xNav.MoveToFirstAttribute())
            {
                xNav.SetValue(p_ListID);
            }
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into myFields
            InsertNode("/dfs:myFields/dfs:dataFields/tns:" + InnerXPath + "", p_FieldInfo.GetTemplateElementDef());
        }

    }

    //View.xml
    public class XSN_View : XSNFile
    {
        private Dictionary<string, string> outComes;

        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "view1.xsl";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            outComes = p_Context.OutComes;
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            if (!InnerXPath.Equals("WorkflowHistory"))
            {
                //"/xsl:stylesheet/xsl:template/html/body/div/table/tbody"
                string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
                InsertNode(_viewPath, p_FieldInfo.GetViewElementDef());
            }
        }

        //
        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                StringBuilder def = new StringBuilder();
                string _LookupFormTableHead = "<tr style=\"MIN-HEIGHT: 31px\" class=\"xdTableOffsetRow\">"
                                              + "<td class=\"xdTableOffsetCellLabel\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-RIGHT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<h4>"
                                              + "<span class=\"xdlabel\">{0} - {1}</span>"
                                              + "</h4>"
                                              + "</td>"
                                              + "<td class=\"xdTableOffsetCellComponent\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-LEFT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>";
                def.AppendFormat(_LookupFormTableHead, p_XListInfo.ListTitle, ctypeInfo.ContentTypeName);

                #region Get Top Three Field expect ID&ContentType

                int fieldMax = 0;
                List<XFieldInfo> viewFields = new List<XFieldInfo>();
                List<XFieldInfo> fieldList = new List<XFieldInfo>();
                if (ctypeInfo.HasView)
                {
                    fieldList = ctypeInfo.ViewFieldList;
                }
                else
                {
                    fieldList = ctypeInfo.FieldInfoList;
                }
                foreach (XFieldInfo fld in fieldList)
                {
                    //控制ID字段只读
                    if (fld.InternalName.Equals("ID") || fld.InternalName.Equals("ContentType"))
                    {
                        continue;
                    }
                    //
                    if (fld.Hidden || fld.FieldInfoType.Equals(FieldInfoType.Calculated))
                    {
                        continue;
                    }

                    //if (fld.FieldInfoType.Equals(FieldInfoType.LookUp))
                    //{
                    //    continue;
                    //}

                    if (fieldMax == 3)
                    {
                        break;
                    }
                    viewFields.Add(fld);
                    fieldMax++;
                }

                #endregion

                def.AppendFormat("<table style=\"BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 373px;"
                                  +
                                  " BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; BORDER-TOP-STYLE: none; TABLE-LAYOUT: fixed; BORDER-LEFT-STYLE: none\""
                                  + " class=\"xdRepeatingTable msoUcTable\" title=\"\" border=\"1\""
                                  + " xd:CtrlId=\"CTRL48\" xd:widgetIndex=\"0\">");
                //colgroup
                def.AppendFormat("<colgroup>");
                for (int i = 0; i < viewFields.Count; i++)
                {
                    def.AppendFormat("<col></col>");
                }
                def.AppendFormat("</colgroup>");

                def.AppendFormat("<tbody class=\"xdTableHeader\"><tr style=\"MIN-HEIGHT: 19px\">");
                foreach (XFieldInfo fld in viewFields)
                {
                    def.AppendFormat(
                        "<td style=\"TEXT-ALIGN: center; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; BORDER-RIGHT: medium none; PADDING-TOP: 1px\">"
                        + "<div><h5 style=\"FONT-WEIGHT: normal\"><strong>{0}</strong></h5></div></td>", fld.DisplayName);
                }
                def.AppendFormat("</tr></tbody>");

                def.AppendFormat("<tbody xd:xctname=\"RepeatingTable\">");
                def.AppendFormat("<xsl:for-each select=\"/dfs:myFields/dfs:dataFields/tns:" + InnerXPath + "\"><tr>");

                foreach (XFieldInfo sFieldInfo in viewFields)
                {
                    def.Append(sFieldInfo.GetViewSubElementDef());
                }

                def.AppendFormat("</tr></xsl:for-each></tbody></table>");
                //string LookupFormTableEnd = "<div class=\"optionalPlaceholder\" xd:xmlToEdit=\"{0}_72\" tabIndex=\"0\""
                //                            + " xd:action=\"xCollection::insert\" style=\"WIDTH: 373px\">Insert item"
                //                            + " </div>"
                //                            + " </div>"
                //                            + " </td>"
                //                            + " </tr>";
                string LookupFormTableEnd = " </div>"
                                            + " </td>"
                                            + " </tr>";
                string lkpFieldUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
                def.AppendFormat(LookupFormTableEnd, lkpFieldUniqueName);

                InsertNode(_viewPath, def.ToString());
            }
        }

        //
        public void AppendFieldInfoSubDef(XListInfo p_XListInfo, List<XFieldInfo> viewFields)
        {
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                StringBuilder def = new StringBuilder();
                string _LookupFormTableHead = "<tr style=\"MIN-HEIGHT: 31px\" class=\"xdTableOffsetRow\">"
                                              + "<td class=\"xdTableOffsetCellLabel\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-RIGHT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<h4>"
                                              + "<span class=\"xdlabel\">{0} - {1}</span>"
                                              + "</h4>"
                                              + "</td>"
                                              + "<td class=\"xdTableOffsetCellComponent\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-LEFT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>";
                def.AppendFormat(_LookupFormTableHead, p_XListInfo.ListTitle, ctypeInfo.ContentTypeName);

                #region Get Top Three Field expect ID&ContentType

                #endregion

                def.AppendFormat("<table style=\"BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 373px;"
                                  +
                                  " BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; BORDER-TOP-STYLE: none; TABLE-LAYOUT: fixed; BORDER-LEFT-STYLE: none\""
                                  + " class=\"xdRepeatingTable msoUcTable\" title=\"\" border=\"1\""
                                  + " xd:CtrlId=\"CTRL48\" xd:widgetIndex=\"0\">");
                //colgroup
                def.AppendFormat("<colgroup>");
                for (int i = 0; i < viewFields.Count; i++)
                {
                    def.AppendFormat("<col></col>");
                }
                def.AppendFormat("</colgroup>");

                def.AppendFormat("<tbody class=\"xdTableHeader\"><tr style=\"MIN-HEIGHT: 19px\">");
                foreach (XFieldInfo fld in viewFields)
                {
                    def.AppendFormat(
                        "<td style=\"TEXT-ALIGN: center; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; BORDER-RIGHT: medium none; PADDING-TOP: 1px\">"
                        + "<div><h5 style=\"FONT-WEIGHT: normal\"><strong>{0}</strong></h5></div></td>", fld.DisplayName);
                }
                def.AppendFormat("</tr></tbody>");

                def.AppendFormat("<tbody xd:xctname=\"RepeatingTable\">");
                def.AppendFormat("<xsl:for-each select=\"/dfs:myFields/dfs:dataFields/tns:" + InnerXPath + "\"><tr>");

                foreach (XFieldInfo sFieldInfo in viewFields)
                {
                    def.Append(sFieldInfo.GetViewSubElementDef());
                }

                def.AppendFormat("</tr></xsl:for-each></tbody></table>");
                //string LookupFormTableEnd = "<div class=\"optionalPlaceholder\" xd:xmlToEdit=\"{0}_72\" tabIndex=\"0\""
                //                            + " xd:action=\"xCollection::insert\" style=\"WIDTH: 373px\">Insert item"
                //                            + " </div>"
                //                            + " </div>"
                //                            + " </td>"
                //                            + " </tr>";
                string LookupFormTableEnd = " </div>"
                                            + " </td>"
                                            + " </tr>";
                string lkpFieldUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
                def.AppendFormat(LookupFormTableEnd, lkpFieldUniqueName);

                InsertNode(_viewPath, def.ToString());
            }
        }

        public void AppendSubmitToHostHead(string HeadName)
        {
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            string submitToHostHead = "<tr class=\"xdTableOffsetRow\">"
                                      + "<td colSpan=\"2\""
                                      + " style=\"PADDING-RIGHT: 1px; PADDING-LEFT: 1px;\""
                                      + " class=\"xdTableOffsetCellLabel\">"
                                      + "<div align=\"left\">"
                                      + HeadName
                                      + "</div>"
                                      + "</td>"
                                      + "</tr>";
            InsertNode(_viewPath, submitToHostHead);
        }

        public void AppendSubmitToHostButton()
        {
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            string submitToHostButton = string.Empty;
            int count = 1;
            foreach (string outCome in outComes.Keys)
            {
                submitToHostButton += "<input class=\"langFont\" title=\"\" type=\"button\""
                                      + " value=\""
                                      + outCome
                                      + "\""
                                      + " xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\""
                                      + " xd:xctname=\"Button\" xd:CtrlId=\"CTRLO" + count + "\" tabIndex=\"0\""
                                      + " style=\"width:auto\"/>   ";
                count++;
            }
            string submitToHostView = "<tr class=\"xdTableOffsetRow\">"
                                      + "<td colSpan=\"2\""
                                      + " style=\"PADDING-RIGHT: 1px; PADDING-LEFT: 1px;\""
                                      + " class=\"xdTableOffsetCellLabel\">"
                                      + "<div align=\"left\">"
                                      + submitToHostButton
                                      + "</div>"
                                      + "</td>"
                                      + "</tr>"
                                      + "<tr class=\"xdTableOffsetRow\">"
                                      + "<td colSpan=\"2\""
                                      + " style=\"PADDING-RIGHT: 1px; PADDING-LEFT: 1px;\""
                                      + " class=\"xdTableOffsetCellLabel\">"
                                      + "<div align=\"left\">"
                                      + "</div>"
                                      + "</td>"
                                      + "</tr>";

            InsertNode(_viewPath, submitToHostView);
        }
    }

    //Choices.xsd
    public class XSN_Choices_XSD : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "choices.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            if (!p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) &&
                !p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice)) return;
            //insert ref
            string refPath = "/xsd:schema/xsd:element[@name='root']/xsd:complexType/xsd:all";
            string refDef = string.Format(
                "<xsd:element ref=\"{0}\" minOccurs=\"0\" maxOccurs=\"1\"></xsd:element>", p_FieldInfo.UniqueName);
            InsertNode(refPath, refDef);

            //insert element
            InsertNode("/xsd:schema", p_FieldInfo.GetChoiceXSDElementDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
            }
        }
    }

    //Choices.xml
    public class XSN_Choices_XML : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "choices.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice))
            {
                //insert root
                InsertNode("/root", p_FieldInfo.GetChoiceXMLElementDef());
            }
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
            }
        }
    }

    //Manifest.xsf
    public class XSN_Manifest : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "manifest.xsf";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            AppendExtension(p_Context.G_Site_Url, p_Context.G_XSN_Url);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into xmlToEdit
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Note) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Url))
            {
                string _xmlToEditPath = "/xsf:xDocumentClass/xsf:views/xsf:view/xsf:editing";
                InsertNode(_xmlToEditPath, p_FieldInfo.GetManifestXmlToEditDef());
            }

            if (!p_FieldInfo.FieldInfoType.Equals(FieldInfoType.LookUp)) return;
            //Insert into File
            string _filePath = "/xsf:xDocumentClass/xsf:package/xsf:files";
            InsertNode(_filePath, p_FieldInfo.GetManifestFileDef());
            //Insert into dataobject
            string _dataobjectPath = "/xsf:xDocumentClass/xsf:dataObjects";
            InsertNode(_dataobjectPath, p_FieldInfo.GetManifestDataObjectDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
                //AppendSubFormEditing(p_XListInfo, ctypeInfo);
                //AppendSubFormMenuArea(p_XListInfo, ctypeInfo);
            }
        }

        public void AppendSubmitToHost(Dictionary<string, string> outComes)
        {
            if (outComes.Count > 0)
            {
                InitialSubmitToHost();
                int count = 1;
                foreach (string outCome in outComes.Values)
                {
                    XPathNavigator _sXNav;
                    string submitToHost;
                    //Add RuleSetAction
                    _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass/xsf:views/xsf:view/xsf:unboundControls", XmlNSManager);
                    submitToHost = string.Format("<xsf:button name=\"CTRLO{0}\"><xsf:ruleSetAction ruleSet=\"ruleSet_O{0}\" /></xsf:button>", count);
                    if (_sXNav != null) _sXNav.AppendChild(submitToHost);
                    if (!string.IsNullOrEmpty(outCome))
                    {
                        //Add SubmitToHostAdapter
                        _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass/xsf:dataAdapters", XmlNSManager);
                        submitToHost = string.Format("<xsf:submitToHostAdapter name=\"{0}\" submitAllowed=\"yes\" />", outCome);
                        if (_sXNav != null) _sXNav.AppendChild(submitToHost);
                    }
                    //Add SubmitAction
                    _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass/xsf:ruleSets", XmlNSManager);
                    submitToHost = string.Format("<xsf:ruleSet name=\"ruleSet_O{0}\"><xsf:rule caption=\"O{0}\" isEnabled=\"yes\">", count);
                    if (!string.IsNullOrEmpty(outCome))
                    {
                        submitToHost += string.Format("<xsf:submitAction adapter=\"{0}\" />", outCome);
                    }
                    submitToHost += "<xsf:closeDocumentAction promptToSaveChanges=\"no\" /></xsf:rule></xsf:ruleSet>";
                    if (_sXNav != null) _sXNav.AppendChild(submitToHost);
                    count++;
                }
            }
        }

        private void InitialSubmitToHost()
        {
            XPathNavigator _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass", XmlNSManager);
            string submitToHostInitial = "<xsf:submit caption=\"Submit\" disableMenuItem=\"no\" onAfterSubmit=\"close\" showStatusDialog=\"no\" >"
                + "<xsf:errorMessage>The form cannot be submitted because of an error.</xsf:errorMessage></xsf:submit>"
                + "<xsf:ruleSets /><xsf:dataAdapters />";
            if (_sXNav != null) InsertNode("/xsf:xDocumentClass", submitToHostInitial);
            _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass/xsf:views/xsf:view", XmlNSManager);
            submitToHostInitial = "<xsf:unboundControls />";
            if (_sXNav != null) InsertNode("/xsf:xDocumentClass/xsf:views/xsf:view", submitToHostInitial);
        }

        private void AppendExtension(string p_Site_Url, string p_XSN_Url)
        {
            XPathNavigator _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass", XmlNSManager);
            string extensionDef = "<xsf:extensions>"
                                   + "<xsf:extension name=\"SolutionDefinitionExtensions\">"
                                   + "<xsf2:solutionDefinition runtimeCompatibility=\"client\">"
                                   + "<xsf2:offline openIfQueryFails=\"yes\" cacheQueries=\"yes\" />"
                                   +
                                   "<xsf2:server formLocale=\"zh-CN\" isPreSubmitPostBackEnabled=\"no\" isMobileEnabled=\"no\" />"
                                   + "<xsf2:solutionPropertiesExtension branch=\"contentTypeTemplate\">"
                                   +
                                   "<xsf2:contentTypeTemplate site=\"{0}\" path=\"template.xsn\" name=\"Form_template\""
                                   + " description=\"Fill out this form.\""
                                   + " browserEnable=\"no\" />"
                                   + "</xsf2:solutionPropertiesExtension>"
                                   + "</xsf2:solutionDefinition>"
                                   + "<xsf3:solutionDefinition>"
                                   + "<xsf3:baseUrl relativeUrlBase=\"{1}\" />"
                                   + "</xsf3:solutionDefinition>"
                                   + "</xsf:extension>"
                                   + "</xsf:extensions>";
            extensionDef = string.Format(extensionDef, p_Site_Url, p_XSN_Url);
            if (_sXNav != null) _sXNav.AppendChild(extensionDef);
        }

        private void AppendSubFormEditing(XListInfo p_XListInfo, ContentTypeInfo ctypeInfo)
        {
            StringBuilder xmlNodeStr = new StringBuilder();
            string ctypeUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
            xmlNodeStr.AppendFormat(
                "<xsf:xmlToEdit name=\"{0}_72\" item=\"/dfs:myFields/dfs:dataFields/tns:" + InnerXPath + "\" container=\"/dfs:myFields\">",
                ctypeUniqueName);
            xmlNodeStr.AppendFormat(
                "<xsf:editWith caption=\"{0}\" xd:autogeneration=\"template\" component=\"xCollection\">",
                p_XListInfo.UniqueName);
            xmlNodeStr.AppendFormat(
                "<xsf:fragmentToInsert><xsf:chooseFragment parent=\"dfs:dataFields\" innerFragment=\"tns:" + InnerXPath + "\" ><tns:WorkflowHistory>",
                p_XListInfo.UniqueName, ctypeInfo.UniqueName, ctypeInfo.ContentTypeId);
            foreach (XFieldInfo sFieldInfo in ctypeInfo.FieldInfoList)
            {
                if (sFieldInfo.DisplayName == "ID")
                {
                    xmlNodeStr.AppendFormat("<tns:{0}>1</tns:{0}>", sFieldInfo.UniqueName);
                }
                else
                {
                    xmlNodeStr.AppendFormat(sFieldInfo.GetTemplateElementDef());
                }
            }
            xmlNodeStr.AppendFormat(
                "</tns:WorkflowHistory></xsf:chooseFragment></xsf:fragmentToInsert></xsf:editWith></xsf:xmlToEdit>");
            InsertNode("/xsf:xDocumentClass/xsf:views/xsf:view/xsf:editing", xmlNodeStr.ToString());
        }

        private void AppendSubFormMenuArea(XListInfo p_XListInfo, ContentTypeInfo ctypeInfo)
        {
            string edirAreaStr = "<xsf:button action=\"xCollection::insertBefore\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1} before\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::insertAfter\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1} after\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::remove\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Remove {1}\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::insert\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1}\" showIf=\"immediate\"/>";
            string ctypeUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
            edirAreaStr = string.Format(edirAreaStr, ctypeUniqueName,
                ctypeInfo.ContentTypeName);
            InsertNode("/xsf:xDocumentClass/xsf:views/xsf:view/xsf:menuArea", edirAreaStr);
        }
    }

    //builtincontrolsschema.xsd
    public class XSN_Builtincontrolsschema : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "builtincontrolsschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }
    }

    //rootschema.xsd
    public class XSN_Rootschema : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "rootschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }
    }

    //Lookup.xsd
    public class XSN_Lookup : XSNFile
    {
        public bool Initial(WFXSNOperator p_Context)
        {
            TemplateName = "lookup.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
        }
    }

    //package.ddf
    public class XSN_DDF
    {
        private string TemplateName { get; set; }

        public string SavePath { get; private set; }

        public bool SaveToLocal
        {
            get { return _saveToLocal; }
            set { _saveToLocal = value; }
        }

        private bool _saveToLocal;

        public void Initial(WFXSNOperator p_Context)
        {
            try
            {
                TemplateName = "package.ddf";
                SaveToLocal = p_Context.G_SaveToLocal;
                SavePath = p_Context.SaveFolder + "\\" + TemplateName;

                File.Copy(p_Context.XSNTemplateFolder + TemplateName, SavePath, true);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}